using Unity.Mathematics;

namespace DA.AnimGraph {
    internal struct FloatLink {
        private readonly AUID name;
        private readonly LinkSourceType sourceType;
        private readonly EaseType easeType;
        public readonly bool useClamp;
        public readonly float2 clampRange;
        public float value { get; private set; }
        AlphaEase ease;

        public FloatLink(in FloatLinkDesc desc) {
            name = desc.name;
            sourceType = desc.sourceType;
            useClamp = desc.useClamp;
            clampRange = desc.clampRange;
            value = desc.defaultValue;
            ease = default;
            ease.easeFunctionType = desc.easeFunctionType;
            ease.SetDuration(desc.easeTime);
            easeType = desc.easeType;
        }

        internal float Evaluate(bool onEnter, in EvaluateContext evaluateContext, in GraphContext graphContext, in ScopeContext scope) {
            if (scope.disableBlackboardUpdate) return value;
            if (sourceType == LinkSourceType.Const) return value;

            float newValue = value;

            switch (sourceType) {
                case LinkSourceType.Blackboard:
                    graphContext.blackboard.GetValue(name, ref newValue);
                    break;
            }

            if (useClamp) {
                newValue = math.clamp(newValue, clampRange.x, clampRange.y);
            }

            if (easeType != EaseType.None && 0 != ease.duration) {
                if (onEnter) {
                    ease.SetInitValue(newValue);
                } else {
                    if (!newValue.IsNear(ease.goalValue)) {
                        ease.NewEase_Weight(newValue);
                    }
                    ease.Update(evaluateContext.deltaTime);
                    newValue = ease.outputValue;
                }
            }

            value = newValue;
            return value;
        }
    }
}
